跳到主要内容

go-micro-v3 框架整体介绍

go-micro v3组件

  • 注册(Registry):提供了服务发现机制
  • 选择器(Selector):能够实现负载均衡
  • 传输(Transport):服务与服务之间通信接口
  • 代理(Broker):提供异步通信的消息发布、订阅接口
  • 编码(Codec):消息传输到两端时进行编码与解码
  • Server服务端,Client客户端

image-20221103234920786

go-micro v3技术栈

  • 注册中心&配置中心
  • 链路追踪
  • 熔断
  • 限流
  • 日志中心
  • 监控

注册中心和配置中心consul集群

  • docker-compose镜像引入consul集群版
  • base基础工程添加consul
  • consul控制面板添加配置

配置docker-compose的consul集群

version: '3'
services:
# 注册中心集群版本设置
consul1:
image: cap1573/consul
container_name: node1
# 以 server 模式启动
command: agent -server -bootstrap-expect=3 -node=node1 -bind=0.0.0.0 -client=0.0.0.0 -datacenter=dc1
consul2:
image: cap1573/consul
container_name: node2
# 以 server 模式启动
command: agent -server -retry-join=node1 -bootstrap-expect=3 -node=node2 -bind=0.0.0.0 -client=0.0.0.0 -datacenter=dc1
depends_on:
# 依赖consul1启动好之后
- consul1
consul3:
image: cap1573/consul
container_name: node3
# 以 server 模式启动
command: agent -server -retry-join=node1 -bootstrap-expect=3 -node=node3 -bind=0.0.0.0 -client=0.0.0.0 -datacenter=dc1
depends_on:
# 依赖consul1启动好之后
- consul1
# 添加对外暴露的节点 启动控制面板
consul4:
image: consul
container_name: node4
command: agent -retry-join=node1 -node=node4 -bind=0.0.0.0 -client=0.0.0.0 -datacenter=dc1 -ui
ports:
- 8500:8500
depends_on:
- consul2
- consul3
# 启动
docker-compose up

访问:http://127.0.0.1:8500/ui/dc1/services/consul/instances

image-20221104221322741

image-20221104221400829

base服务添加consul完成注册中心

go get github.com/asim/go-micro/plugins/registry/consul/v3
func main() {
consul := consul.NewRegistry(func(options *regstry.Options) {
options.Addrs = []string{
// 如果放到 docker-compose 也可以是服务名称
// 这里暂时是本地可以写 localhost
"localhost:8500",
}
});

// ... 其他省略代码

service := micro.NewService(
micro.Name("base-wj"),
micro.Version("latest"),
micro.Registry(consul),
)

service.Init()

base.RegisterBaseHandler(service.Server(), new(handler.BaseHandler))

// 启动服务
if err := service.Run(); err != nil {
//输出启动失败信息
common.Fatal(err)
}
}

编写完成之后,我们可以启动一下服务。

image-20221104223228628

image-20221104223243628

我们可以看到base服务已经注册到consul

配置中心

我们另外在项目的平级目录下新建common目录用于配置配置项。

go mod init git.xxx.com/用户名/common

go get github.com/asim/go-micro/v3/config
go get github.com/asim/go-micro/plugins/config/source/consul/v3

config.go

package common

import (
"github.com/asim/go-micro/plugins/config/source/consul/v3"
"github.com/asim/go-micro/v3/config"
"strconv"
)

func GetConsulConfig(host string, port int64, prefix string) (config.Config, error) {
consulSource := consul.NewSource(
//设置配置中心的地址
consul.WithAddress(host+":"+strconv.FormatInt(port, 10)),
//设置前缀,不设置 /micro/config
consul.WithPrefix(prefix),
consul.StripPrefix(true),
)
conf, err := config.NewConfig()
if err != nil {
return conf, err
}
err = conf.Load(consulSource)
return conf, err
}

写完之后,可以上传一下代码,可以让同级目录下的可以进行引入使用对应的配置内容。

然后我们继续到base服务代码中获取配置项

func main() {
consul := consul.NewRegistry(func(options *registry.Options) {
options.Addrs = []string{
"localhost:8500",
}
})
//2.配置中心,存放经常变动的变量
consulConfig, err := common.GetConsulConfig("localhost", consulPort, "/micro/config")
if err != nil {
//common.Error(err)
fmt.Println(err)
}
fmt.Println(consulConfig)

service := micro.NewService(
micro.Name("base-wj"),
micro.Version("latest"),
micro.Registry(consul),
)

service.Init()

base.RegisterBaseHandler(service.Server(), new(handler.BaseHandler))

// 启动服务
if err := service.Run(); err != nil {
//输出启动失败信息
common.Fatal(err)
}
}

启动base服务后去consul中创建key/value

image-20221104224854974

{
"host": "127.0.0.1",
"port": 3306,
"user": "root",
"pwd": "123456",
"database": "paas"
}
注意

这里一定要选择json

编写mysql结构体和使用配置中心连接mysql

结构体和刚才建立的json内容需要一一对应

我们在commom模块中新建mysql.go

package common

import "github.com/asim/go-micro/v3/config"

// MysqlConfig 创建结构体
type MysqlConfig struct {
Host string `json:"host"`
User string `json:"user"`
Pwd string `json:"pwd"`
Database string `json:"database"`
Port string `json:"port"`
}

func GetMysqlFromConsul(config config.Config, path ...string) *MysqlConfig {
mysqlConfig := &MysqlConfig{}
config.Get(path...).Scan(mysqlConfig)
return mysqlConfig
}

commmon模块编写之后,需要上传一下,不然别的模块的还是无法使用新的代码,别的模块等到上传完之火,还需要重新go get一下更新一下代码。


从配置中心获取配置并使用gorm连接mysql

func main() {
//需要本地启动,mysql,consul中间件服务
//1.注册中心
//consul := consul.NewRegistry(func(options *registry.Options) {
// options.Addrs = []string{
// consulHost + ":" + strconv.FormatInt(consulPort, 10),
// }
//})
consul := consul.NewRegistry(func(options *registry.Options) {
options.Addrs = []string{
"localhost:8500",
}
})
//2.配置中心,存放经常变动的变量
consulConfig, err := common.GetConsulConfig("localhost", consulPort, "/micro/config")
if err != nil {
//common.Error(err)
fmt.Println(err)
}
fmt.Println(consulConfig)
//3.使用配置中心连接 mysql
// 这里的path是相对于 /micro/config 目录路径
mysqlInfo := common.GetMysqlFromConsul(consulConfig, "mysql")
//初始化数据库
db, err := gorm.Open("mysql", mysqlInfo.User+":"+mysqlInfo.Pwd+"@("+mysqlInfo.Host+":3306)/"+mysqlInfo.Database+"?charset=utf8&parseTime=True&loc=Local")
if err != nil {
//命令行输出下,方便查看错误
fmt.Println(err)
}
defer db.Close()
//禁止复表 创建表不带s
db.SingularTable(true)

// 创建服务
service := micro.NewService(
micro.Name("base-wj"),
micro.Version("latest"),
micro.Registry(consul),
)
service.Init()

base.RegisterBaseHandler(service.Server(), new(handler.BaseHandler))

// 启动服务
if err := service.Run(); err != nil {
//输出启动失败信息
common.Fatal(err)
}
}

docker-compose里配置一个mysql5.6的服务

version: '3'
services:
# 注册中心集群版本设置
consul1:
image: cap1573/consul
container_name: node1
# 以 server 模式启动
command: agent -server -bootstrap-expect=3 -node=node1 -bind=0.0.0.0 -client=0.0.0.0 -datacenter=dc1
consul2:
image: cap1573/consul
container_name: node2
# 以 server 模式启动
command: agent -server -retry-join=node1 -bootstrap-expect=3 -node=node2 -bind=0.0.0.0 -client=0.0.0.0 -datacenter=dc1
depends_on:
# 依赖consul1启动好之后
- consul1
consul3:
image: cap1573/consul
container_name: node3
# 以 server 模式启动
command: agent -server -retry-join=node1 -bootstrap-expect=3 -node=node3 -bind=0.0.0.0 -client=0.0.0.0 -datacenter=dc1
depends_on:
# 依赖consul1启动好之后
- consul1
# 添加对外暴露的节点 启动控制面板
consul4:
image: consul
container_name: node4
command: agent -retry-join=node1 -node=node4 -bind=0.0.0.0 -client=0.0.0.0 -datacenter=dc1 -ui
ports:
- 8500:8500
depends_on:
- consul2
- consul3
# 添加数据库
paas-mysql:
image: cap1573/mysql:5.6
environment:
MYSQL_ROOT_PASSWORD: 123456
container_name: paas-mysql
# 我们这里换个端口,本地已经有3306了
ports:
- "3308:3306"
# 需要将重要的数据挂盘
volumes:
- ./mysql:/var/lib/mysql

然后我们重新启动一下docker-compose up

image-20221104230543134

测试连接通过,表示服务启动成功。连接成功后,并新建一个数据库.然后再base服务中不要忘记安装gorm的一些需要的mysql驱动。

注意
db, err := gorm.Open("mysql", mysqlInfo.User+":"+mysqlInfo.Pwd+"@("+mysqlInfo.Host+":3306)/"+mysqlInfo.Database+"?charset=utf8&parseTime=True&loc=Local")

这里如果你本机和容器映射的端口都是3306无所谓,如果你本地有,你换了一个,这里也得换,所以你对应的配置中心的端口也得换。后面如果是在容器里连接,那就可能会换成对应的服务名。

重新启动base服务

image-20221104232259143